package hotel.quartz.oversea.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import hotel.base.oversea.constant.CommonBaseConstants;
import hotel.base.oversea.constant.CommonUrlConstants;
import hotel.base.oversea.service.impl.BaseServiceImpl;
import hotel.base.oversea.utils.BeanCopierUtil;
import hotel.base.oversea.utils.GsonUtils;
import hotel.base.oversea.utils.JacksonUtil;
import hotel.base.oversea.utils.Result;
import hotel.quartz.oversea.entity.domain.JobAndTrigger;
import hotel.quartz.oversea.entity.domain.JobAndTriggerVo;
import hotel.quartz.oversea.entity.form.JobForm;
import hotel.quartz.oversea.mapper.JobAndTriggerMapper;
import hotel.quartz.oversea.mapper.JobDetailMapper;
import hotel.quartz.oversea.service.JobAndTriggerService;
import hotel.quartz.oversea.util.JobRestTemplateUtils;
import hotel.quartz.oversea.util.JobUtil;
import hotel.quartz.oversea.vo.SysCommonBase;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhangjinzheng
 * @date 2019-11-22
 */
@Service
@Slf4j
public class JobAndTriggerServiceImpl extends BaseServiceImpl<JobAndTrigger> implements JobAndTriggerService {
    @Autowired
    private RestTemplate template;
    @Autowired
    private Scheduler scheduler;

    @Autowired
    private JobAndTriggerMapper jobAndTriggerMapper;

    @Autowired
    private JobDetailMapper jobDetailMapper;
    /**
     * 添加并启动定时任务
     *
     * @param form 表单参数 {@link JobForm}
     * @return {@link JobDetail}
     * @throws Exception 异常
     */
    @Override
    public void addJob(JobForm form) throws Exception {
        // 启动调度器
        scheduler.start();

        // 构建Job信息
        JobDetail jobDetail = JobBuilder.newJob(JobUtil.getClass(form.getJobClassName()).getClass()).withIdentity(form.getJobClassName(), form.getJobGroupName()).build();

        // Cron表达式调度构建器(即任务执行的时间)
        CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule(form.getCronExpression());

        //根据Cron表达式构建一个Trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(form.getJobClassName(), form.getJobGroupName()).withSchedule(cron).build();
        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error("【定时任务】创建失败！", e);
            throw new Exception("【定时任务】创建失败！");
        }

    }

    /**
     * 删除定时任务
     *
     * @param form 表单参数 {@link JobForm}
     * @throws SchedulerException 异常
     */
    @Override
    public void deleteJob(JobForm form) throws SchedulerException {
        scheduler.pauseTrigger(TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName()));
        scheduler.unscheduleJob(TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName()));
        scheduler.deleteJob(JobKey.jobKey(form.getJobClassName(), form.getJobGroupName()));
    }

    /**
     * 暂停定时任务
     *
     * @param form 表单参数 {@link JobForm}
     * @throws SchedulerException 异常
     */
    @Override
    public void pauseJob(JobForm form) throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey(form.getJobClassName(), form.getJobGroupName()));
    }

    /**
     * 恢复定时任务
     *
     * @param form 表单参数 {@link JobForm}
     * @throws SchedulerException 异常
     */
    @Override
    public void resumeJob(JobForm form) throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey(form.getJobClassName(), form.getJobGroupName()));
    }

    /**
     * 重新配置定时任务
     *
     * @param form 表单参数 {@link JobForm}
     * @throws Exception 异常
     */
    @Override
    public void cronJob(JobForm form) throws Exception {
        if(null != form.getCronExpression() && !"".equals(form.getCronExpression()) && !"".equals(form.getCronExpression()) && !form.getCronExpression().contains("undefined")){
            try {
                TriggerKey triggerKey = TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName());
                // 表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(form.getCronExpression());

                CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

                // 根据Cron表达式构建一个Trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder.withMisfireHandlingInstructionDoNothing()).build();

                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            } catch (SchedulerException e) {
                log.error("【定时任务】更新失败！", e);
                throw new Exception("【定时任务】创建失败！");
            }
        }
        if(null != form.getDescription() && !"".equals(form.getDescription()) && !form.getDescription().contains("undefined")){
            try {
                Map map = new HashMap();
                map.put("jobClassName",form.getJobClassName());
                map.put("description",form.getDescription());
                jobDetailMapper.updateDesc(map);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }

    /**
     * 查询定时任务列表
     *
     * @param currentPage 当前页
     * @param pageSize    每页条数
     * @return 定时任务列表
     */
    @Override
    public PageInfo<JobAndTrigger> list(Integer currentPage, Integer pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<JobAndTrigger> list = jobAndTriggerMapper.getJobList();
        return new PageInfo<>(list);
    }

    @Override
    public List<JobAndTriggerVo> getJobList() {
        List<JobAndTriggerVo> listVo = new ArrayList<>();

        List<JobAndTrigger> list = jobAndTriggerMapper.getJobList();
        if(list.isEmpty() || list.size() == 0){
            JobAndTrigger jobAndTrigger = new JobAndTrigger();
            jobAndTrigger.setJobName("当前数据为空！");
            list.add(jobAndTrigger);
        }else{
            Map<String,String> map = new HashMap();
            Map queryMap = new HashMap();
            queryMap.put("head", CommonBaseConstants.JOB_UP_DOWN);
            Result rs = JobRestTemplateUtils.post(CommonUrlConstants.ADMIN_HOST+"/sysCommonBase/queryCommonBaseByGroupHead", GsonUtils.GsonString(queryMap),template);
            log.info("批量上下架:"+ GsonUtils.GsonString(rs));
            if(!ObjectUtils.isEmpty(rs.getData())){
                List<SysCommonBase> sysCommonBaseList = null;
                try{
                    sysCommonBaseList = GsonUtils.jsonToList(rs.getData().toString(), SysCommonBase.class);
                }catch (Exception e){
                    sysCommonBaseList = JacksonUtil.jsonToList(rs.getData().toString(), SysCommonBase.class);
                    e.printStackTrace();
                }
                if(null != sysCommonBaseList && sysCommonBaseList.size()>0)
                    for (SysCommonBase s:sysCommonBaseList){
                        if(!ObjectUtils.isEmpty(s.getOpValue())){
                            String[] arr = s.getOpValue().split("\\.");
                            map.put(arr[arr.length-1],s.getPlatformValue());
                        }
                    }
            }
            for (JobAndTrigger j:list){
                JobAndTriggerVo jobAndTriggerVo = new JobAndTriggerVo();
                BeanCopierUtil.copy(j,jobAndTriggerVo);
                String jobName = j.getJobClassName();
                if(!ObjectUtils.isEmpty(jobName)){
                    String[] thisjn = jobName.split("\\.");
                    if(null != map.get(thisjn[thisjn.length-1])){
                        jobAndTriggerVo.setOpenStatus("【2线-开启】");
                    }
                    listVo.add(jobAndTriggerVo);
                }
            }
        }
        return listVo;

    }
    @Override
    public JobAndTrigger getJobOne(String groupName, String className) {
        Map map = new HashMap();
        map.put("className",className);
        map.put("groupName",groupName);
        JobAndTrigger one = jobAndTriggerMapper.getJobOne(map);
        return one;

    }
}
